package com.didang;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import com.didang.annotation.Column;
import com.didang.annotation.Id;
import com.didang.annotation.Table;
import com.didang.exception.PkValueIsNullException;

/**
 * model帮助类
 * @author didang
 *
 */
public class ModelHelper {

	
	/**
	 * 获取Map,列名为Key,字段为Value
	 * @param clazz
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 */
	public static Map<String, String> getColumnFiledMap(Class clazz) throws SecurityException, NoSuchFieldException{
		Map<String, String> columnFieldMap = new HashMap();
		Field[] fields = clazz.getDeclaredFields();
		String  fieldName = null;
		String  columnName = null;
		for(Field field : fields){
			fieldName = field.getName();
			columnName = getColumnName(clazz, fieldName);
			columnFieldMap.put(columnName, fieldName);
		}
		return columnFieldMap;
	}
	
	
	/**
	 * 获取表名
	 * @param model
	 * @return
	 */
	public static String getTableName(Class clazz){
		Table table = (Table) clazz.getAnnotation(Table.class);
		if(table == null || "".equals(table.value()))return clazz.getSimpleName().toLowerCase();
		return table.value();
	}
	
	/**
	 * 获取主键和对应的值
	 * @param model
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws PkValueIsNullException 
	 * @throws NoSuchFieldException 
	 */
	public static Map<String, Object> getPrimaryKeysAndValues(Model model) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, PkValueIsNullException, NoSuchFieldException{
		Map<String, Object> map = new HashMap<String, Object>();
		Field[] fields = model.getClass().getDeclaredFields();
		String fieldName = "";
		String pk = "";
		Object value = null;
		String columnName = "";
		for(Field field: fields){
			fieldName = field.getName();
			Id id = field.getAnnotation(Id.class);
			if(id == null) continue;
			columnName = getColumnName(model.getClass(), fieldName);
			Method method = model.getClass().getDeclaredMethod("get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1,fieldName.length()), null);
			value = method.invoke(model, null);
			if(value != null){
				map.put(columnName, value);
			}else{
				throw new PkValueIsNullException(pk);
			}
		}
		return map.size()>0?map:null;
	}
	
	/**
	 * 获取所有列名和对应的值
	 * @param model
	 * @return
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws NoSuchFieldException 
	 */
	public static Map<String, Object> getColumnsAndValues(Model model) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException{
		Map<String, Object> map = new HashMap<String, Object>();
		Field[] fields = model.getClass().getDeclaredFields();
		String fieldName = "";
		Object value = null;
		String columnName = "";
		for(Field field: fields){
			fieldName = field.getName();
			columnName = getColumnName(model.getClass(), fieldName);
			Method method = model.getClass().getDeclaredMethod("get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1,fieldName.length()), null);
			value = method.invoke(model, null);
			if(value != null){
				map.put(columnName, value);
			}
		}
		return map.size()>0?map:null;
	}
	
	/**
	 * 获取普通列名和对应的值
	 * @param model
	 * @return
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws NoSuchFieldException 
	 */
	public static Map<String, Object> getNormalColumnsAndValues(Model model) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException{
		Map<String, Object> map = new HashMap<String, Object>();
		Field[] fields = model.getClass().getDeclaredFields();
		String fieldName = "";
		Object value = null;
		String columnName = "";
		for(Field field: fields){
			fieldName = field.getName();
			if(ModelHelper.isPk(model, fieldName)) continue;
			columnName = getColumnName(model.getClass(), fieldName);
			Method method = model.getClass().getDeclaredMethod("get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1,fieldName.length()), null);
			value = method.invoke(model, null);
			if(value != null){
				map.put(columnName, value);
			}
		}
		return map.size()>0?map:null;
	}
	
	/**
	 * 判断是否主键
	 * @param model
	 * @param column
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 */
	public static boolean isPk(Model model,String column) throws SecurityException, NoSuchFieldException{
		Field field = model.getClass().getDeclaredField(column);
		Id id = field.getAnnotation(Id.class);
		return id==null?false:true;
	}

	
	/**
	 * 获取列名
	 * @param clazz
	 * @param filedName
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 */
	public static String getColumnName(Class clazz,String filedName) throws SecurityException, NoSuchFieldException{
		Field field = clazz.getDeclaredField(filedName);
		Column column = field.getAnnotation(Column.class);
		if(column ==null || "".equals(column.value())){
			return filedName;
		}else{
			return column.value().toLowerCase();
		}
	}
}
